using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using ZyGame;
using ZyGame.Drawing;
using ZyGame.Avatar;
using System.Collections;
using UnityEngine.Networking;
using System.Runtime.CompilerServices;
using UnityEngine.Bindings;
using System.Reflection;
using System.Diagnostics;

namespace Example
{
    public class AvatarExample : MonoBehaviour
    {
        public WebGLAvatar avatar;
        public bool InternalNetwork;
        public Color color;

        //public GameObject ske;
        //public GameObject mesh;

        //public SkinnedMeshRenderer skinned;

        private List<string> layers = new List<string>();
        List<string> array;

        public void Awake()
        {
            
            //MeshFilter filter = mesh.GetComponent<MeshFilter>();

            //SkinnedMeshRenderer ren = new GameObject("combine").AddComponent<SkinnedMeshRenderer>();

            //ren.sharedMesh = mesh.GetComponent<MeshFilter>().sharedMesh;// new Mesh();
            ////ren.sharedMesh.name = "combine";
            ////ren.sharedMesh.vertices = filter.sharedMesh.vertices;
            ////ren.sharedMesh.triangles = filter.sharedMesh.triangles;
            ////ren.sharedMesh.uv = filter.sharedMesh.uv;
            ////ren.sharedMesh.uv2 = filter.sharedMesh.uv2;
            ////ren.sharedMesh.uv3 = filter.sharedMesh.uv3;

            //ren.bones = ske.transform.Find("joint/root").GetComponentsInChildren<Transform>();

            //Transform t = ren.bones.ToList().Find(x => x.name == "Neck_M");
            //Client.Console.WriteLine(ren.bones[6].name);
            //ren.transform.parent = t;
            //ren.transform.localPosition = Vector3.zero;
            //ren.transform.localRotation = Quaternion.identity;
            //ren.transform.localScale = Vector3.one;

            //ren.transform.parent = ske.FindChild("mesh").transform;
            //ren.rootBone = ske.transform.Find("joint/root");
            //ren.sharedMesh.boneWeights = new BoneWeight[ren.sharedMesh.vertices.Length];
            //int index = ren.bones.ToList().FindIndex(x => x.name == "Neck_M");
            //Client.Console.WriteLine(index);
            //for (int i = 0; i < ren.sharedMesh.boneWeights.Length; i++)
            //{
            //    ren.sharedMesh.boneWeights[i] = new BoneWeight() { boneIndex0 = index, weight0 = 1 };
            //}
            //ren.sharedMesh.bindposes = new Matrix4x4[ren.sharedMesh.boneWeights.Length];
            ////Client.Console.WriteLine(skinned.sharedMesh.bindposes.Length);
            //for (int i = 0; i < ren.sharedMesh.boneWeights.Length; i++)
            //{
            //    ren.sharedMesh.bindposes[i] = t.worldToLocalMatrix * ren.transform.localToWorldMatrix;
            //}
            //ren.sharedMesh.RecalculateBounds();

            //return;
            //array = Enum.GetNames(typeof(Element)).ToList();
            //ZyGame.Client.Events.Register(EventNames.GRAFFITI_INITIALIZED_COMPLETED, OnEntryGraffiti);
            //ZyGame.Client.Events.Register(EventNames.CREATE_LAYER_COMPLETED, OnNewDrawingLayer);
            //ZyGame.Client.Events.Register(EventNames.DELETE_LAYER_COMPLETED, OnDeleteDrawingLayer);
            //InitializedDropdown("graffiti", array, Graffiti);
            //InitializedDropdown("perview", array, avatar.PreviewAsset);
            //InitializedDropdown("upload", array, avatar.UploadAsset);

            //List<string> paints = Enum.GetNames(typeof(PaintBrush)).ToList();
            //InitializedDropdown("Drawing/paint", paints, args => { avatar.SetPaintbrushType(args + 1); });
            //transform.Find("Drawing/LayerSize").GetComponent<Slider>().onValueChanged.AddListener(avatar.SetLayerSize);
            //transform.Find("Drawing/PaintSize").GetComponent<Slider>().onValueChanged.AddListener(avatar.SetPaintbrushWidth);
            //transform.Find("Drawing/alpha").GetComponent<Slider>().onValueChanged.AddListener(avatar.SetLayerAlpha);
            //GameObject.Find("Canvas/save (5)").GetComponent<Button>().onClick.AddListener(() => SelectionGirl(1));
            //GameObject.Find("Canvas/save (6)").GetComponent<Button>().onClick.AddListener(() => SelectionGirl(0));
            //GameObject.Find("Canvas/save (7)").GetComponent<Button>().onClick.AddListener(NewColor);
            //GameObject.Find("Canvas/save").GetComponent<Button>().onClick.AddListener(() => Client.Drawing.Save("test"));
            //GameObject.Find("Canvas/Drawing/newLayer").GetComponent<Button>().onClick.AddListener(NewLayer);
            //GameObject.Find("Canvas/Drawing/import").GetComponent<Button>().onClick.AddListener(Import);
            //GameObject.Find("Canvas/Drawing/delete").GetComponent<Button>().onClick.AddListener(Delete);
            //GameObject.Find("Canvas/Drawing/undo").GetComponent<Button>().onClick.AddListener(Undo);
            //GameObject.Find("Canvas/random_color").GetComponent<Button>().onClick.AddListener(ChangeColor);
            //GameObject.Find("Canvas/Drawing/newLayer (1)").GetComponent<Button>().onClick.AddListener(Publishing);
            //GameObject.Find("Canvas/importconfig").GetComponent<Button>().onClick.AddListener(ImportConfig);
            //transform.Find("Drawing").gameObject.SetActive(false);
        }

        public static IEnumerator RequestPublishingElementDatas(string groupName, Action<List<ElementData>, Exception> callback)
        {
            using UnityWebRequest request = UnityWebRequest.Get(AvatarSetting.address + "avatar/api/v1/items/base?model_name=" + groupName);//"avatar/api/v1/items?page=1&page_size=100&type=-1&model_name=mesh_girl_001_skeleton");
            Client.Console.WriteLine(request.url);
            yield return request.SendWebRequest();
            if (!request.isDone || request.result != UnityWebRequest.Result.Success)
            {
                callback(null, new Exception(string.Format("{0}\n{1}\n{2}", request.url, request.error, request.downloadHandler.text)));
                yield break;
            }
            Client.Console.WriteLine(request.downloadHandler.text);
            ResponsePublishingElementDatas responsePublishingElementDatas = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePublishingElementDatas>(request.downloadHandler.text);
            if (responsePublishingElementDatas.code != 200)
            {
                throw new Exception(responsePublishingElementDatas.msg);
            }

            List<ElementData> elementDatas = new List<ElementData>();
            if (responsePublishingElementDatas.data.list != null)
            {
                foreach (var item in responsePublishingElementDatas.data.list)
                {
                    elementDatas.Add(new ElementData()
                    {
                        icon = item.icon,
                        model = item.model,
                        model_name = item.model_name,
                        publish_status = item.publish_status,
                        name = item.name,
                        id = item.id.ToString(),
                        element = (Element)item.element,
                        texture = item.texture
                    });
                }
            }

            callback(elementDatas, null);
        }






        private void Graffiti(int index)
        {
            ElementData data = Client.Avatar.GetElementData(index);
            Client.Events.Register(EventNames.NOTICE_SAVED_GRAFFITI_DATA, _ =>
            {
                Client.Events.Clear(EventNames.NOTICE_SAVED_GRAFFITI_DATA);
                avatar.Save("");
            });
            avatar.ElementGraffiti(Newtonsoft.Json.JsonConvert.SerializeObject(data));
        }

        void Runnable_Initialized(object args)
        {
            Client.Events.Unregister(EventNames.INITIALIZED_COMPLATED_EVENT, Runnable_Initialized);
            string eleData = "[{\"id\":\"6412c1e5bc351ed9d3c11de4\",\"element\":0,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_boy_001_skeleton.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_boy_001_skeleton.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/\",\"group_type\":0,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11de5\",\"element\":1,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_bodyB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_bodyb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_boyskin_001.png\",\"group_type\":2,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11de7\",\"element\":13,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_earB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_earb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_boyHead_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11de8\",\"element\":4,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_eyeB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_eyeb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_boyHead_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11de9\",\"element\":6,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_eyebrowB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_eyebrowb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_eyebrowB_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11dea\",\"element\":7,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_eyelashB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_eyelashb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_eyelashB_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11ded\",\"element\":2,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_headB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_headb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_boyHead_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11def\",\"element\":9,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_mouthB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_mouthb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_boyHead_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11df0\",\"element\":8,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_noseB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_noseb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_boyHead_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"},{\"id\":\"6412c1e5bc351ed9d3c11df1\",\"element\":5,\"name\":\"\",\"model_name\":\"mesh_boy_001_skeleton\",\"icon\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/icons/mesh_pupilB_001_icon.png\",\"publish_status\":1,\"price\":0,\"model\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_pupilb_001.assetbundle\",\"texture\":\"https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/elements/texB_pupilB_001.png\",\"group_type\":1,\"fbx_url\":\"\",\"status\":0,\"extra_key\":\"\",\"extra_value\":\"\"}]";
            List<ElementData> elements = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ElementData>>(eleData);
            elements.Add(new ElementData()
            {
                name = "6412c23bbc351ed9d3c11df8",
                model_name = "mesh_girl_001_skeleton",
                element = (Element)41,
                icon = "https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/girl/icons/mesh_bobbyPinG_002_icon.png",
                model = "https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/girl/webgl/mesh_bobbyping_002.assetbundle",
                texture = "https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/girl/elements/texB_bobbyPinG_002.png",
                publish_status = 1
            });
            Runnable_ResponsePublishingElementDatas(elements, null);
        }

        void Runnable_ResponsePublishingElementDatas(List<ElementData> elements, Exception exception)
        {
            if (exception != null)
            {
                Client.Console.WriteError(exception);
                return;
            }
            void Combine(object args)
            {
                Client.Events.Unregister(EventNames.SET_ELEMENT_DATA_COMPLATED, Combine);
                avatar.Combine();
            }
            Client.Events.Register(EventNames.SET_ELEMENT_DATA_COMPLATED, Combine);
            avatar.SetElementData(Newtonsoft.Json.JsonConvert.SerializeObject(elements));
        }

        void InitializedDropdown(string name, List<string> items, UnityEngine.Events.UnityAction<int> callback)
        {
            Dropdown component = this.transform.Find(name).GetComponent<Dropdown>();
            component.ClearOptions();
            component.AddOptions(items);
            component.onValueChanged.RemoveAllListeners();
            component.onValueChanged.AddListener(callback);
        }

        public void SelectionGirl(int type)
        {
            string url = string.Empty;
            if (type == 0)
            {
                url = "https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/boy/webgl/mesh_boy_001_skeleton.assetbundle";
            }
            else
            {
                url = "https://avatar-oss.oss-cn-beijing.aliyuncs.com/6/9/girl/webgl/mesh_girl_001_skeleton.assetbundle";
            }
            AvatarOptions initData = new()
            {
                skeleton = url,
                address = InternalNetwork ? "https://meta.playmonstergalaxy.com/" : "https://meta.playmonstergalaxy.com/",
                config = Resources.Load<TextAsset>("bones").text,
                userId = "4",
                pid = 1
            };
            Client.Events.Register(EventNames.INITIALIZED_COMPLATED_EVENT, Runnable_Initialized);
            avatar.Initialized(Newtonsoft.Json.JsonConvert.SerializeObject(initData));
        }


        public void Undo()
        {
            avatar.Undo(this.transform.Find("Drawing/Toggle").GetComponent<Toggle>().isOn ? 0 : 1);
        }

        public void Save()
        {
            void SaveGraffiti(object args)
            {
                Client.Events.Unregister(EventNames.NOTICE_SAVED_GRAFFITI_DATA, SaveGraffiti);
                Client.Drawing.ExitGraffiti();
            }

            ZyGame.Client.Events.Register(EventNames.NOTICE_SAVED_GRAFFITI_DATA, SaveGraffiti);
            avatar.Save("");
            layers.Clear();
        }

        public void ChangeControlle(int state)
        {
            CameraCtrl.instance.SetControllrtType((ControllerState)state);
        }

        public void Delete()
        {
            avatar.DeleteLayer();
        }

        public void Publishing()
        {
            avatar.ExportConfig(Guid.NewGuid().ToString());
        }

        public void NewLayer()
        {
            avatar.NewLayer(Guid.NewGuid().ToString());
        }

        public void Import()
        {
            avatar.ImportGraffitiTexture();
        }

        public void ImportConfig()
        {
            //ElementData data = new ElementData()
            //{
            //    name = "641bcdd25d90da05c258931a",
            //    model_name = "mesh_boy_001_skeleton",
            //    element = Element.Tshirt,
            //    icon = "http://rungirl.smartgo.fun/2/1679543760000_icon.png",
            //    model = "https://moga-test-store.s3.us-west-2.amazonaws.com/1/boy/webgl/mesh_shirtb_001.assetbundle",
            //    texture = "https://moga-test-store.s3.us-west-2.amazonaws.com/9/1680228448000.png",
            //    publish_status = 2
            //};
            //avatar.ElementGraffiti(Newtonsoft.Json.JsonConvert.SerializeObject(data));
            //transform.Find("Drawing").gameObject.SetActive(true);
        }

        private void OnDeleteDrawingLayer(object args)
        {
            if (args == null)
            {
                return;
            }

            if (!layers.Contains(args.ToString()))
            {
                return;
            }

            layers.Remove(args.ToString());
            InitializedDropdown("Drawing/layers", layers, args => { avatar.SelectionLayer(layers[args]); });
        }

        private void OnEntryGraffiti(object args)
        {
            transform.Find("Drawing").gameObject.SetActive(true);
        }

        private void OnNewDrawingLayer(object args)
        {
            if (args == null)
            {
                return;
            }

            if (layers.Contains(args.ToString()))
            {
                return;
            }

            layers.Add(args.ToString());
            InitializedDropdown("Drawing/layers", layers, args => { avatar.SelectionLayer(layers[args]); });
        }
        public void NewColor()
        {
            DrawingSetting.instance.SetPaintbrushColor(color);
        }
        public void ChangeColor()
        {
            color = new Color(UnityEngine.Random.Range(0, 1f), UnityEngine.Random.Range(0, 1f), UnityEngine.Random.Range(0, 1f), 1);
            DrawingSetting.instance.SetPaintbrushColor(color);
        }
    }
}